<template>
  <div style="height: 100%; width: 100%">
    <canvas :ref="'canvas_' + fileId" :style="{width: width +'px', height: height + 'px'}" class="canvas-class" @mousedown="clickPoint" />
    <el-dialog
      width="30%"
      title="请选择批次"
      :visible.sync="innerVisible"
      @close="dialogClose"
      append-to-body
    >
      <el-table :data="batchRecords" stripe style="width: 100%">
        <el-table-column align="center" prop="batch" label="批次" min-width="30%" />
        <el-table-column align="center" label="状态" min-width="40%">
          <template slot-scope="scope">
            <el-tag :color="lineColor[scope.row.status].color">{{ lineColor[scope.row.status].label }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" min-width="30%">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              @click="selectBatch(scope.row)"
            >
              选择
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'LineDrawPlaneVue',
  props: {
    width: {
      type: Number,
      default: 500
    },
    height: {
      type: Number,
      default: 500
    },
    fileId: {
      type: Number,
      default: null
    },
    lineArr: {
      type: Array,
      default: function() {
        return []
      }
    },
    clickCallBack: {
      type: Function,
      default: function() {}
    },
    roleKey: { type: String, default: '' },
    status: { type: Number, default: undefined }
  },
  data() {
    return {
      /* 颜色图例 */
      lineColor: {
        '-1': { color: '#cccc98', label: '待验收' },
        '10': { color: '#80c9b5', label: '验收合格' },
        '11': { color: '#eb9494', label: '验收不合格' },
        '20': { color: '#80c9b5', label: '复核合格' },
        '21': { color: '#eb9494', label: '复核不合格' },
        0: { color: '#ccc', label: '未报验' }
      },
      /* 划线大小 */
      penPointSize: 10,
      /* 记录所有的渲染点位 */
      inspectPoints: [],
      innerVisible: false,
      batchRecords: []
    }
  },
  watch: {
    fileId: {
      handler: function() {
        this.$nextTick(() => {
          this.init()
        })
      },
      immediate: true
    },
    lineArr: {
      deep: true,
      handler() {
        this.init()
      }
    },
    roleKey(val) {
      this.init()
    },
    status(val) {
      this.init()
    }
  },
  methods: {
    /* 初始化 */
    init() {
      this.inspectPoints = []
      this.renderCanvasBg()
    },
    /* 渲染底图 */
    renderCanvasBg() {
      const that = this
      var canvas = this.$refs['canvas_' + this.fileId]
      const img = new Image()
      img.onload = () => {
        const imgW = img.width
        const imgH = img.height
        const ctx = canvas.getContext('2d')
        const scaling = this.getImgScaling(imgW, imgH, that.width, that.height)
        const realWidth = imgW / scaling
        const realHeight = imgH / scaling
        this.originalPoint = [realWidth / 2, realHeight / 2]
        canvas.width = realWidth
        canvas.height = realHeight
        ctx.drawImage(img, 0, 0, realWidth, realHeight)
        canvas.style.width = imgW / scaling + 'px'
        canvas.style.height = imgH / scaling + 'px'
        that.backgroundImg = img
        let lineArr = this.lineArr || []
        const status = this.status
        const roleKey = this.roleKey
        if (status !== undefined) {
          lineArr = lineArr.filter(item => status === (roleKey ? item.roleResult[roleKey] || 0 : item.status))
        }
        // 渲染画线
        for (const line of lineArr) {
          this.renderCanvasData(ctx, line.points, roleKey ? (line.roleResult[roleKey] || 0) : line.status, line.sourceId, line.batch)
        }
      }
      img.src = process.env.VUE_APP_BASE_API + '/file/download?fileKey=' + this.fileId
    },
    /* 渲染绘制 */
    renderCanvasData(ctx, lines = [], status, sourceId = '-1', batch) {
      const canvasW = ctx.canvas.clientWidth
      const canvasH = ctx.canvas.clientHeight
      const inspectObj = { sourceId, status, batch, lineArr: [] }
      if (lines.length === 0) {
        return
      }
      const color = status ? this.lineColor[status + ''].color : '#ccc'
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i]
        const points = line.points || []
        const firstPoint = points[0]

        ctx.beginPath()
        ctx.strokeStyle = color
        ctx.lineWidth = line.pointSize || this.penPointSize
        ctx.lineCap = 'round'
        ctx.lineJoin = 'round'
        ctx.moveTo(firstPoint[0] * canvasW, firstPoint[1] * canvasH)
        // 记录画图的点位信息
        const lineItem = { lineWidth: ctx.lineWidth, points: [] }
        for (let i = 1; i < points.length; i++) {
          const point = points[i]
          const x = point[0] * canvasW
          const y = point[1] * canvasH
          ctx.lineTo(x, y)
          lineItem.points.push({ x, y })
        }
        inspectObj.lineArr.push(lineItem)
        ctx.stroke()
      }
      this.inspectPoints.push(inspectObj)
    },
    /**
     * 获取图片压缩比例
     * @param imgW 图片宽度
     * @param imgH 图片高度
     * @param containerW 容器宽度
     * @param containerH 容器高度
     */
    getImgScaling(imgW, imgH, containerW, containerH) {
      const scalingW = imgW / containerW
      const scalingH = imgH / containerH
      return scalingW > scalingH ? scalingW : scalingH
    },
    /* 点击事件 */
    clickPoint(e) {
      const x = e.offsetX
      const y = e.offsetY
      const batchRecords = this.inspectPoints.filter(item => item.batch && this.checkAreaMatch(x, y, item.lineArr))
      if (batchRecords.length > 1) {
        batchRecords.sort((a, b) => a.batch - b.batch)
        this.innerVisible = true
        this.batchRecords = batchRecords
      } else if (batchRecords.length === 1) {
        this.clickCallBack({ objectId: batchRecords[0].sourceId, batch: batchRecords[0].batch })
      }
    },
    /**
     * 判断区域匹配
     * @param x 点X
     * @param y 点Y
     * @param lines 线段集合
     * @return {boolean}
     */
    checkAreaMatch(x, y, lines = []) {
      for (const line of lines) {
        const lineWidth = line.lineWidth
        for (const point of line.points) {
          if (point.x + lineWidth >= x &&
            point.x - lineWidth <= x &&
            point.y + lineWidth >= y &&
            point.y - lineWidth <= y
          ) {
            return true
          }
        }
      }
      return false
    },
    /**
     * 关闭弹窗处理
     */
    dialogClose() {
      this.batchRecords = []
    },
    /**
     * 选择记录
     * @param data 数据
     */
    selectBatch(data) {
      this.batchRecords = []
      this.innerVisible = false
      this.clickCallBack({ objectId: data.sourceId, batch: data.batch })
    }
  }
}
</script>

<style scoped>

</style>
